package ctrconfig

import (
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"time"
	"fmt"
	"strings"
	"cloud_worm/util/umodels/mysqldb/dbmanager"
	"net/url"
	"cloud_worm/wormweb/controllers/ctrutil"
	"cloud_worm/util/uhttp"
	"io/ioutil"
	"encoding/json"
	"cloud_worm/util/umodels/mysqldb"
	"cloud_worm/util/uid"
)

type LoginCtr struct {
	beego.Controller
	
	UserInfo       		*dbmanager.WebUser // 用户信息
	IsLogin        		bool               // 标记是否登陆
	IsAllowReferer 		bool               // 标记未允许referer
}

// LoginCtr.getUserInfo 基于session中username取用户信息
func (l *LoginCtr) getUserInfo() *dbmanager.WebUser {
	user := &dbmanager.WebUser{Username: l.GetSession(ctrutil.SessionUserName).(string), Status: mysqldb.StatusValid}
	err := user.Read("username", "status")
	if err != nil {
		logs.Error(fmt.Sprintf("GetUserInfo read error: %s", err.Error()))
		return nil
	}
	
	return user
}

// LoginCtr.logoutInner 去登陆信息，从session中删除登陆信息
func (l *LoginCtr) logoutInner() {
	l.IsLogin = false
	l.DelSession(ctrutil.SessionUserName)
	return
}

// LoginCtr.checkReferer 检查是是否为合法Referer
func (l *LoginCtr) checkReferer() {
	referer := l.Ctx.Input.Header("Referer")
	if referer == "" {
		l.IsAllowReferer = false
		return
	}
	
	u, err := url.Parse(referer)
	if err != nil {
		l.IsAllowReferer = false
		return
	}
	
	part := strings.Split(u.Host, ":")[0]
	
	if strings.ToLower(part) == l.Ctx.Input.Domain() {
		l.IsAllowReferer = true
	} else {
		l.IsAllowReferer = false
	}
	return
}

/**
 检查是否登陆过
 */
func (l *LoginCtr) checkLogin() {
	
	l.IsLogin = l.GetSession(ctrutil.SessionUserName) != nil
	if l.IsLogin {
		// 登陆过
		l.UserInfo = l.getUserInfo()
		if l.UserInfo != nil {
			
			l.UserInfo.LastLoginTime = time.Now().Unix()
			err := l.UserInfo.Update("last_login_time")
			if err != nil {
				logs.Error(fmt.Sprintf("update error: %s", err.Error()))
			}
		} else {
			// 没有登陆，直接跳转到登陆页面
			l.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeAuthRedirect, "no login, please login first", nil)
			l.ServeJSON()
			l.StopRun()
			return
		}
	} else {
		// 没有登陆，直接跳转到登陆页面
		l.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeAuthRedirect, "no login, please login first", nil)
		l.ServeJSON()
		l.StopRun()
		return
	}
	
	return
}

// LoginCtr.LoginByPassWord 用户名和密码登陆
func (l *LoginCtr) LoginByPassWord()  {
	type UserInfo struct {
		Username 		string		`json:"username"`
		Password 		string		`json:"password"`
	}
	body, err := ioutil.ReadAll(l.Ctx.Request.Body)
	if err != nil {
		l.logoutInner()
		l.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, err.Error(), nil)
		l.ServeJSON()
		return
	}
	var input UserInfo
	if err = json.Unmarshal(body, &input); err != nil {
		l.logoutInner()
		l.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, "input Unmarshal error.", nil)
		l.ServeJSON()
		return
	}
	if input.Username == mysqldb.SelectStrAll || input.Password == mysqldb.SelectStrAll {
		l.logoutInner()
		l.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input params error.", nil)
		l.ServeJSON()
		return
	}

	webUser := &dbmanager.WebUser{Username: input.Username, Status: mysqldb.StatusValid}
	if err := webUser.Read("username", "status"); err != nil {
		l.logoutInner()
		l.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input params error.", nil)
		l.ServeJSON()
		return
	}
	if uid.PasswordMatch(webUser.Password, input.Password) == false {
		l.logoutInner()
		l.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input params error.", nil)
		l.ServeJSON()
		return
	}

	// 设置登陆成功的信息
	l.IsLogin = true
	l.SetSession(ctrutil.SessionUserName, webUser.Username)
	l.UserInfo = webUser

	// 登入成功 跳到首页 todo:首页地址
	l.Data["json"] = uhttp.CreateOkResponse(nil)
	l.ServeJSON()
	return
}

// LoginCtr.LoginByUrl 通过url登录，todo：待实现
func (l *LoginCtr) LoginByUrl() {
	//redirectUrl := ctrutil.AccountURL + l.Ctx.Input.Scheme() + "://" + l.Ctx.Request.Host + l.Ctx.Request.URL.String()
	//
	//auth := comaccount.AppAuth{
	//	AppKey: comaccount.AuthApplyKey,
	//	Redirect: comaccount.AuthDirect,
	//	LastLoginIP: l.Ctx.Request.Host,
	//	LastLoginTime: time.Now().Unix(),
	//}
	//logs.Debug(l.Ctx.Request.Header)
	//mtgk, err := l.Ctx.Request.Cookie("MTGK")
	//if err != nil {
	//	ticket := l.GetString("ticket")
	//	if ticket == "" {
	//		l.Redirect(redirectUrl, http.StatusFound)
	//		//l.Data["json"] = comhttp.CreateErrResponse(comhttp.RespCodeAuthRedirect, redirectUrl, nil)
	//		//l.ServeJSON()
	//		l.StopRun()
	//		return
	//	}
	//
	//	auth.Ticket = ticket
	//	if auth.CreateSecKey() != nil {
	//		l.Redirect(redirectUrl, http.StatusFound)
	//		//l.Data["json"] = comhttp.CreateErrResponse(comhttp.RespCodeAuthRedirect, redirectUrl, nil)
	//		//l.ServeJSON()
	//		l.StopRun()
	//		return
	//	}
	//} else {
	//	auth.TicketGlobalCookie = mtgk.Value
	//}
	//logs.Debug(auth)
	//
	//data, err := auth.Auth()
	//if err != nil {
	//	if err == comaccount.AuthErr403 {
	//		//l.Data["json"] = comhttp.CreateErrResponse(comhttp.RespCodeAuthRedirect, comaccount.AuthForbiddenUrl, nil)
	//	} else {
	//		//l.Data["json"] = comhttp.CreateErrResponse(comhttp.RespCodeAuthErr, err.Error(), nil)
	//	}
	//	l.Redirect(redirectUrl, http.StatusFound)
	//	//l.ServeJSON()
	//	l.StopRun()
	//	return
	//}
	//logs.Debug("login success.....")
	//
	//u := &dbmanager.WolWebUser{Username: data.UserName}
	//err = u.Read("username")
	//if err != nil && strings.Contains(err.Error(), mysqldb.NoMysqlRow) {
	//	// 数据库中没有这个用户，插入新的用户
	//	u.Username = data.UserName
	//	u.Nickname = data.Parameter.NickName
	//	u.Avatar = data.Parameter.Avatar
	//	u.WorkId = data.Parameter.WorkId
	//	u.Role = ctrutil.RoleGuest // 给登入权限
	//	u.LastLoginTime = time.Now().Unix()
	//	u.Created = time.Now().Unix()
	//	u.Updated = u.Created
	//	u.Status = mysqldb.StatusValid
	//	err = u.Insert()
	//	if err != nil {
	//		logs.Error(fmt.Sprintf("Insert error: %s", err.Error()))
	//		// todo: 不知道干嘛，可能会有容错操作
	//	} else {
	//		logs.Info(fmt.Sprintf("Insert user: %s", u.Username))
	//	}
	//} else {
	//	u.Nickname = data.Parameter.NickName
	//	u.Avatar = data.Parameter.Avatar
	//	u.WorkId = data.Parameter.WorkId
	//	u.LastLoginTime = time.Now().Unix()
	//	err := u.Update("last_login_time", "nickname", "avatar", "work_id")
	//	if err != nil {
	//		logs.Error(fmt.Sprintf("update last login time error: %s.", err.Error()))
	//	}
	//}
	//
	//// 设置登陆成功的信息
	//l.IsLogin = true
	//l.SetSession(ctrutil.SESSION_USER_NAME, u.Username)
	//l.SetSession(ctrutil.SESSION_USER_NICKNAME, u.Nickname)
	//l.SetSession(ctrutil.SESSION_USER_AVATAR, u.Avatar)
	//l.UserInfo = u
	return
}
